package cheme.Interpreter.AST.Arithmetic;

import cheme.Interpreter.AST.Interfaces.IAstExpression;
import cheme.Interpreter.AST.Interfaces.IAstType;
import cheme.Interpreter.AST.Interfaces.IAstUnaryOperation;
import cheme.Interpreter.AST.Interfaces.IObserver;
import cheme.Interpreter.AST.Interfaces.ISubject;
import cheme.Interpreter.AST.Interfaces.SubjectCore;

public abstract class AstUnarayOpAstNode implements IAstUnaryOperation
{
	IAstExpression expression = null;
	
	private SubjectCore subjectCore = new SubjectCore(this);

	public AstUnarayOpAstNode()
	{
	}
	
	public AstUnarayOpAstNode(IAstExpression expression)
	{
		super();
		this.expression = expression;
		
		if(null != expression)
		{
			expression.attach(this);
		}
	}

	/**
	 * @return the operand
	 */
	public IAstExpression getOperand()
	{
		return expression;
	}

	/**
	 * @param operand the operand to set
	 */
	public void setOperand(IAstExpression operand)
	{
		if(null != this.expression)
		{
			this.expression.detach(this);
		}
		
		if(null != expression)
		{
			expression.attach(this);
		}
		
		this.expression = operand;
	}

	public ValueationState getValueationState()
	{
		if(null != getOperand())
		{
			return getOperand().getValueationState();
		}
		
		return ValueationState.Unknown;
	}
	
	public IAstType getType()
	{
		return getOperand().getType();
	}
	
	public boolean isUnknown()
	{
		if(null != getOperand())
		{
			return getOperand().isUnknown();
		}
		
		/*
		 * Is it logical to have incomplete expressions (those with a null 
		 * operand) coinsidered as unknown values? Or should it be an error state?
		 * I am thinking the latter; 
		 */
		return false;
	}

	public void notify(ISubject s)
	{
		notifyObservers();
	}
	
	public void attach(IObserver o)
	{
		subjectCore.attach(o);
	}

	public void detach(IObserver o)
	{
		subjectCore.detach(o);
	}

	public void notifyObservers()
	{
		subjectCore.notifyObservers();
	}
}
